$ManifestFileClass = New-PSClass ManifestFile {

	note Path 
	note SourceCheckSum
	note ExecutedCheckSum
	note MetaData
	
	constructor {
		$this.Path = $this.Path -replace '^\\?(.*?)\\*$', '$1'
	}
}

$ManifestClass = New-PSClass Manifest {

	note File
	Constructor {
	  $ManifestFileClass.AttachTo($this.File)
	}
	
	method MatchingFiles {
	  $pattern = $Args[0]
	  foreach ($file in $this.File)
	  {
	    if ($file.path -match $pattern)
	    {
	      $file
	    }
	  }
	}
}

$ManifestFileBrokerClass = New-PSClass ManifestFileBroker {

	note -private MD5Provider
	note -private ShaProvider

	constructor {
		$private.MD5Provider = New-Object "System.Security.Cryptography.MD5CryptoServiceProvider"
		$private.ShaProvider = New-Object "System.Security.Cryptography.SHA1CryptoServiceProvider"
	}

	method FileChecksum {
		[System.IO.FileInfo] $filename = $Args[0]
		$fs = New-Object "system.io.FileStream" ($filename, [system.io.filemode]::Open, [system.IO.FileAccess]::Read)
		
		try {
			$md5Hash = [system.Convert]::ToBase64String($private.MD5Provider.ComputeHash($fs))  
			$fs.Position =0
			$shaHash = [system.Convert]::ToBase64String($private.ShaProvider.ComputeHash($fs))  
			"{0}{1}{2:d6}" -f $md5Hash,$shaHash,$filename.Length
		} -finally {
			$fs.Close()
		}
	}


	method XmlFromPath {
		[system.IO.DirectoryInfo]$path = $Args[0]
		[array]$files = $Args[1]
		[string]$filter = $Args[2]
		
		if ($files -eq $null)
		{
			$files = Get-ChildItem $path -recurse -Filter $filter | where {$_ -is [System.IO.FileInfo]}
		}
		else
		{
			#$files = $files | where {$_ -is [System.IO.FileInfo] }
			$files = $files | where {$_ -is [System.IO.FileInfo] -and ($filter -eq "" -or $_.name -like $filter)}
		}
		
		[xml]$manifestXml = "<DatabaseManifest></DatabaseManifest>"
		
		$dm = $manifestXml.selectSingleNode("/DatabaseManifest") 
		
		foreach ($file in $files)
		{
			$node = $manifestXml.CreateElement("file")
			[void] $dm.AppendChild($node)
			[void] $node.SetAttribute("Path",$file.Fullname.Remove(0,$path.FullName.Length))
			[void] $node.SetAttribute("SourceCheckSum",$this.FileChecksum($file.FullName))
		}
		$manifestXml
	}
	
	method FromPath {
		$path = $Args[0]
		$files = [array]$Args[1]
		$filter = $Args[2]

		$manifestXml = $this.XmlFromPath($path,$files,$filter)
		
		$manifest = ReadXmlIntoObjectTree $manifestXml 
		[void] $ManifestClass.AttachTo($manifest)
		
		$manifest.file
	}
}
